#ifndef OS_SYSCALL_H
#define OS_SYSCALL_H

#ifdef __cplusplus
extern "C"
{
#endif

#include <types.h>

enum syscall_num_t
{
    // process operator
    SYS_EXIT = 0,
    SYS_FORK,
    SYS_SLEEP,
    SYS_WAITPID,
    SYS_GETPID,
    SYS_GETPPID,
    SYS_GETTID,
    SYS_GETPGID,
    SYS_SETPGID,
    SYS_SETUID,
    SYS_GETUID,
    SYS_SETGID,
    SYS_GETGID,
    SYS_USLEEP,
    SYS_TSTATUS,
    // device opertor
    SYS_SCANDEV,
    SYS_PROBEDEV,
    // thread control
    SYS_THREAD_CREATE,
    SYS_THREAD_EXIT,
    SYS_THREAD_JOIN,
    SYS_THREAD_CANNEL,
    SYS_THREAD_DETACH,
    SYS_THREAD_CANCELSTATUS,
    SYS_THREAD_CANCELTYPE,
    SYS_THREAD_TESTCANCEL,
    // process control
    SYS_CREATEPROCESS,
    SYS_RESUMEPROCESS,
    SYS_SCHED_YIELD,
    // message queue
    SYS_MSGQUEUEGET,
    SYS_MSGQUEUEPUT,
    SYS_MSGQUEUESEND,
    SYS_MSGQUEUERECV,
    SYS_MUTEX_QUEUE_CREATE,
    SYS_MUTEX_QUEUE_DESTORY,
    SYS_MUTEX_QUEUE_WATI,
    SYS_MUTEX_QUEUE_WAKE,
    // share memory
    SYS_SHAREMEMDOWN,
    SYS_SHAREMEMUP,
    SYS_SHAREMEMGET,
    SYS_SHAREMEMPUT,
    SYS_SHAREMEMMAP,
    SYS_SHAREMEMUNMAP,
    // semaphore
    SYS_SEMGET,
    SYS_SEMPUT,
    SYS_SEMDOWN,
    SYS_SEMUP,
    // log
    SYS_LOGWRITE,
    SYS_LOGREAD,
    SYS_LOGDEL,
    SYS_LOGFIND,
    // file system
    SYS_MKFS,
    SYS_MOUNT,
    SYS_UNMOUNT,
    SYS_READ,
    SYS_WRITE,
    SYS_OPEN,
    SYS_CLOSE,
    SYS_IOCTL,
    SYS_FCNTL,
    SYS_PIPE,
    SYS_UNLINK,
    SYS_FTRUNCATE,
    SYS_FSYNC,
    SYS_DUP,
    SYS_DUP2,
    SYS_RENAME,
    SYS_OPENDIR,
    SYS_CLOSEDIR,
    SYS_READDIR,
    SYS_REWIND,
    SYS_CHDIR,
    SYS_RMDIR,
    SYS_MKDIR,
    SYS_GETCWD,
    SYS_LSEEK,
    SYS_FSTATUS,
    SYS_STATUS,
    SYS_ACCESS,
    SYS_CHMOD,
    SYS_FCHMOD,
    SYS_FASTIO,
    SYS_FASTREAD,
    SYS_FASTWRITE,
    SYS_REWINDDIR,
    SYS_TELL,
    SYS_SELECT,
    SYS_MKFIFO,
    SYS_MOUNTINFO,
    // account manage
    SYS_LOGIN,
    SYS_LOGOUT,
    SYS_USERNAME,
    SYS_USERREGISTER,
    SYS_USERUNREGISTER,
    SYS_USERVERITFY,
    SYS_USERCHPWD,
    // group manage
    SYS_GROUPCREATE,
    SYS_GROUPREMOVE,
    SYS_GROUPADDUSER,
    SYS_GROUPDELUSER,
    // port manage
    SYS_BIND_PORT,
    SYS_UNBIND_PORT,
    SYS_REPLY_PORT,
    SYS_REQUEST_PORT,
    SYS_RECEIVE_PORT,
    // environ
    SYS_GETVER,
    SYS_GETENV,
    SYS_SETENV,
    SYS_UNSETENV,
    SYS_CLEARENV,
    SYS_PUSHENV,
    SYS_ENV,
    // power
    SYS_REBOOT,
    SYS_POWEROFF,
    // exception manage
    SYS_EXCSEND,
    SYS_EXCBLOCK,
    SYS_EXCMASK,
    SYS_EXCCATCH,
    SYS_EXCHANDLER,
    SYS_EXCRET,
    // socket call
    SYS_SOCKETCALL,
    // time
    SYS_TIMES,
    SYS_GETWALLTIME,
    SYS_GETTIMEOFDAY,
    SYS_CLOCK_GETTIME,
    SYS_ALARM,
    SYS_GETTICKS,
    // other
    SYS_MMAP,
    SYS_HEAP,
    SYS_MUNMAP,
    SYS_GETHOSTNAME,
    SYS_CONFIG,
    SYS_MSTATUS,
    SYS_SYSCONFIG,
    SYS_GETFIREWORK,
    SYS_GETDISK,
    SYS_GETVOL,
    SYS_SWAPMEM,
    SYS_EXECVE,
    SYS_DEBUG,
    SYSCALL_MAX
};


#ifdef __ARCH_X86
    typedef uint32_t sc_type;
#else
typedef sc_type sc_type;
#endif

    extern sc_type __syscall0(sc_type num);
    extern sc_type __syscall1(sc_type num, sc_type args0);
    extern sc_type __syscall2(sc_type num, sc_type args0, sc_type args1);
    extern sc_type __syscall3(sc_type num, sc_type args0, sc_type args1, sc_type args2);
    extern sc_type __syscall4(sc_type num, sc_type args0, sc_type args1, sc_type args2, sc_type args3);
    extern sc_type __syscall5(sc_type num, sc_type args0, sc_type args1, sc_type args2, sc_type args3, sc_type args4);

#define syscall0(type, num) \
    (type) __syscall0((sc_type)num)
#define syscall1(type, num, args0) \
    (type) __syscall1((sc_type)num, (sc_type)args0)
#define syscall2(type, num, args0, args1) \
    (type) __syscall2((sc_type)num, (sc_type)args0, (sc_type)args1)
#define syscall3(type, num, args0, args1, args2) \
    (type) __syscall3((sc_type)num, (sc_type)args0, (sc_type)args1, (sc_type)args2)
#define syscall4(type, num, args0, args1, args2, args3) \
    (type) __syscall4((sc_type)num, (sc_type)args0, (sc_type)args1, (sc_type)args2, (sc_type)args3)
#define syscall5(type, num, args0, args1, args2, args3, args4) \
    (type) __syscall5((sc_type)num, (sc_type)args0, (sc_type)args1, (sc_type)args2, (sc_type)args3, (sc_type)args4)

#ifdef __cpluplus
}
#endif
#endif